/**  
 * All rights Reserved, Designed By https://www.cnblogs.com/jiduoduo
 * @Title:  flowabletest.java
 * @Package com.jiduoduo.test
 * @Description:    测试
 * @author: jiduoduo
 * @date:   2022年8月13日
 * @version v1.0
 */
package com.jiduoduo.test;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.flowable.engine.HistoryService;
import org.flowable.engine.ProcessEngine;
import org.flowable.engine.ProcessEngineConfiguration;
import org.flowable.engine.ProcessEngines;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.impl.cfg.StandaloneProcessEngineConfiguration;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.repository.ProcessDefinitionQuery;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.junit.Test;

public class flowabletest {

	/**
	 * 部署流程
	 */
	@Test
	public void testDeploy() {
		// XML：放到src/main/resources下
		// 方式一：会直接读取classpath下面的文件:flowable.cfg.xml(不能修改名字)
//        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//        if(processEngine==null) {
//        	processEngine = ProcessEngineConfiguration
//        		      .createStandaloneProcessEngineConfiguration()
//        		      .buildProcessEngine();
//        }
		// 方式二：通过代码的形式赋值连接
		// 配置数据库相关信息 获取 ProcessEngineConfiguration
//    	ProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration()
//    	    .setJdbcUrl("jdbc:mysql://localhost:3306/myflowable?serverTimezone=UTC&nullCatalogMeansCurrent=true")
//    	    .setJdbcUsername("root")
//    	    .setJdbcPassword("admin")
//    	    .setJdbcDriver("com.mysql.cj.jdbc.Driver")
//    	    .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
		// 获取流程引擎对象
//    	ProcessEngine processEngine = cfg.buildProcessEngine();
		// 方式三：通过自定义文件来
		ProcessEngineConfiguration configuration = ProcessEngineConfiguration
				.createProcessEngineConfigurationFromResource("flowable.cfg.xml");
		ProcessEngine processEngine = configuration.buildProcessEngine();

		RepositoryService repositoryService = processEngine.getRepositoryService();
		Deployment deploy = repositoryService.createDeployment().addClasspathResource("holiday-request.bpmn20.xml")
				.name("请假流程...").category("请假") // 分类
				.tenantId("abc") // 租户id
				.deploy();
		// 根据deployid来获取procdef_id;
		ProcessDefinitionQuery deploymentId = repositoryService.createProcessDefinitionQuery()
				.deploymentId(deploy.getId());
		List<ProcessDefinition> list = deploymentId.list();
		String processDefinitionId = "";
		if (list != null && list.size() > 0) {
			for (ProcessDefinition processDefinition : list) {
				processDefinitionId = processDefinition.getId();
				System.out.println("流程定义ID:" + processDefinition.getId());
				System.out.println("流程定义的名称:" + processDefinition.getName());
				System.out.println("流程定义的key:" + processDefinition.getKey());
				System.out.println("流程定义的版本:" + processDefinition.getVersion());
				System.out.println("资源名称bpmn文件:" + processDefinition.getResourceName());
				System.out.println("资源名称png文件:" + processDefinition.getDiagramResourceName());
				System.out.println("部署对象ID:" + processDefinition.getDeploymentId());
				boolean suspended = processDefinition.isSuspended();
				System.out.println("suspended = " + suspended);
				System.out.println("---------------------------------------------------");
			}
		}

		System.out.println("deploy.getId() = " + deploy.getId());
		System.out.println("deploy.getName() = " + deploy.getName());
		System.out.println("deploy.getCategory() = " + deploy.getCategory());

		// 启动流程实例通过 RuntimeService 对象
		RuntimeService runtimeService = processEngine.getRuntimeService();
		// 构建流程变量
		Map<String, Object> variables = new HashMap<>();
		variables.put("employee", "张三");// 谁申请请假
		variables.put("nrOfHolidays", 7); // 请几天假
		variables.put("description", "年假"); // 请假的原因
		// 启动流程实例，第一个参数是流程定义的id
		ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinitionId, variables);
		// runtimeService.startProcessInstanceById(processDefinitionId);
//				runtimeService.startProcessInstanceByKey("holidayRequest", variables);// 启动流程实例
		// 输出相关的流程实例信息
		System.out.println("流程定义的ID：" + processInstance.getProcessDefinitionId());
		System.out.println("流程实例的ID：" + processInstance.getId());
		System.out.println("当前活动的ID：" + processInstance.getActivityId());
		// 查询managers组的任务
		System.out.println("----------------------------------");
		System.out.println("=========查询managers组的任务========");
		TaskService taskService = processEngine.getTaskService();
		List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("managers").list();
		System.out.println("You have " + tasks.size() + " tasks:");
		String taskId = "";
		for (int i = 0; i < tasks.size(); i++) {
			taskId = tasks.get(i).getId();
			System.out.println((i + 1) + ") " + tasks.get(i).getName() + ":" + tasks.get(i).getId());
		}
		System.out.println("=========审核managers组的任务========");
		variables = new HashMap<String, Object>();
		variables.put("approved", true);
		taskService.complete(taskId, variables);
		// 下一级审核
		System.out.println("----------------------------------");
		System.out.println("=========查询employee的任务========");
		tasks = taskService.createTaskQuery().taskAssignee("张三").list();
		for (int i = 0; i < tasks.size(); i++) {
			taskId = tasks.get(i).getId();
			System.out.println((i + 1) + ") " + tasks.get(i).getName() + ":" + tasks.get(i).getId());
		}
		System.out.println("=========审核employee的任务========");
		variables = new HashMap<String, Object>();
		variables.put("approved", true);
		taskService.complete(taskId, variables);
		// 查看历史
		System.out.println("=========查看历史========");
		HistoryService historyService = processEngine.getHistoryService();
		List<HistoricActivityInstance> listHi = historyService.createHistoricActivityInstanceQuery()
				.processDefinitionId(processDefinitionId).finished().orderByHistoricActivityInstanceEndTime().asc()
				.list();
		for (HistoricActivityInstance historicActivityInstance : listHi) {
			System.out.println(historicActivityInstance.getActivityId() + " took "
					+ historicActivityInstance.getDurationInMillis() + " milliseconds"
					+ historicActivityInstance.getActivityType() + historicActivityInstance.getAssignee() == null ? ""
							: historicActivityInstance.getAssignee());
		}
	}

}
